package com.distribute.config;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.security.web.authentication.session.SessionAuthenticationException;

import com.distribute.common.Constant;
import com.distribute.common.utils.ResponseInfo;
import com.distribute.common.utils.ResponseUtil;
import com.distribute.dto.LoginUser;



@Configuration
public class SecurityHandlerConfig {
	

	/**
	 * 登陆成功，返回Token
	 */
	@Bean
	public AuthenticationSuccessHandler loginSuccessHandler() {
		return new AuthenticationSuccessHandler() {
			@Override
			public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
					Authentication authentication) throws IOException, ServletException {
				LoginUser loginUser = (LoginUser) authentication.getPrincipal();
				loginUser.setPassword(StringUtils.EMPTY);
				request.getSession().setAttribute(Constant.SESSION_USER, loginUser);
			}
		};
	}
	
	/**
	 * 登陆失败
	 */
	@Bean
	public AuthenticationFailureHandler loginFailureHandler() {
		return new AuthenticationFailureHandler() {
			@Override
			public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
					AuthenticationException exception) throws IOException, ServletException {
				String msg = null;
				if (exception instanceof BadCredentialsException) {
					msg = "密码错误";
				}else if(exception instanceof SessionAuthenticationException){
					msg = "账号已登陆，若非本人操作，请修改密码。";
				} else {
					msg = exception.getMessage();
				}
				LoginUser loginUser = new LoginUser();
				loginUser.setUsername(request.getParameter("username"));
				ResponseInfo info = new ResponseInfo(HttpStatus.UNAUTHORIZED.value() + "", msg);
				ResponseUtil.responseJson(response, HttpStatus.UNAUTHORIZED.value(), info);
			}
		};

	}

	/**
	 * 未登录，返回401
	 * @return
	 */
	@Bean
	public AuthenticationEntryPoint authenticationEntryPoint() {
		return new AuthenticationEntryPoint() {
			@Override
			public void commence(HttpServletRequest request, HttpServletResponse response,
					AuthenticationException authException) throws IOException, ServletException {
				String contentType = Constant.checkJsonOrHtml(request);
				if (contentType.equals("text/html")) {
				    Constant.clientRedirect(response, Constant.LOGIN_PAGE_URL);
				} else if (contentType.equals("application/json")) {
					ResponseInfo info = new ResponseInfo(HttpStatus.UNAUTHORIZED.value() + "", "请先登录");
					ResponseUtil.responseJson(response, HttpStatus.UNAUTHORIZED.value(), info);
				}
			}
		};
	}

	/**
	 * 退出处理
	 * 
	 * @return
	 */
	@Bean
	public LogoutSuccessHandler logoutSussHandler() {
		return new LogoutSuccessHandler() {
			@Override
			public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
					Authentication authentication) throws IOException, ServletException {
				request.getSession().invalidate();
				//判断请求类型
		        String contentType = Constant.checkJsonOrHtml(request);
		        if (contentType.equals("text/html")) {
		            Constant.clientRedirect(response, Constant.LOGIN_PAGE_URL);
		        } else if (contentType.equals("application/json")) {
		        	ResponseInfo info = new ResponseInfo(HttpStatus.OK.value() + "", "退出成功");
		        	ResponseUtil.responseJson(response, HttpStatus.OK.value(), info);
		        }
			}
		};
	}
}
